package com.yuanzong.wuliu.common.utils.code;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class PhotoCodeUtils {

    public static Map<String, String> photoCodeMap = new HashMap<>();

    public final static String CODE_VALUE = "codeValue";
    public final static String CODE_IMAGE = "codeImage";
    public final static String CODE_BASE64 = "codeBase64";

    // 验证码宽度
    private static final int WIDTH = 120;
    // 验证码高度
    private static final int HEIGHT = 40;
    // 验证码字符数量
    private static final int CODE_COUNT = 4;
    // 字体大小
    private static final int FONT_SIZE = 30;

    // 使用更清晰的字体
    private static final String[] FONT_NAMES = {
            "Arial", "Verdana", "Tahoma", "Helvetica"
    };

    // 使用高对比度的颜色
    private static final Color[] COLORS = {
            Color.BLACK,
            new Color(0, 0, 128),    // 深蓝
            new Color(139, 0, 0),    // 深红
            new Color(0, 100, 0)     // 深绿
    };

    public static Map<String, Object> generateCaptcha() {
        // 创建内存图像
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        // 设置抗锯齿和文本渲染，使文字更清晰
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // 设置背景色为浅灰色，比纯白色更柔和
        g.setColor(new Color(240, 240, 240));
        g.fillRect(0, 0, WIDTH, HEIGHT);

        // 生成随机验证码
        String captcha = generateRandomCode();
        // 绘制验证码
        drawCaptcha(g, captcha);
        // 释放图形资源
        g.dispose();

        // 将图片转换为字节流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "jpg", outputStream);
        } catch (IOException e) {
            throw new RuntimeException("生成验证码失败", e);
        }

        // 返回结果
        Map<String, Object> result = new HashMap<>();
        result.put(CODE_VALUE, captcha);
        result.put(CODE_IMAGE, outputStream.toByteArray());
        return result;
    }

    /**
     * 生成验证码并返回包含Base64字符串的Map
     * @return Map包含验证码值和Base64格式的图片
     */
    public static Map<String, Object> generateCaptchaBase64() {
        Map<String, Object> captchaMap = generateCaptcha();
        byte[] imageBytes = (byte[]) captchaMap.get(CODE_IMAGE);
        String base64Image = Base64.getEncoder().encodeToString(imageBytes);
        captchaMap.put(CODE_BASE64, "data:image/jpeg;base64," + base64Image);
        return captchaMap;
    }

    private static String generateRandomCode() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < CODE_COUNT; i++) {
            sb.append(random.nextInt(10)); // 0-9的随机数字
        }
        return sb.toString();
    }

    private static void drawCaptcha(Graphics2D g, String code) {
        Random random = new Random();
        for (int i = 0; i < code.length(); i++) {
            // 设置字体
            String fontName = FONT_NAMES[random.nextInt(FONT_NAMES.length)];
            Font font = new Font(fontName, Font.BOLD, FONT_SIZE); // 使用粗体使数字更清晰
            g.setFont(font);

            // 设置颜色
            g.setColor(getRandomColor());

            // 绘制字符
            int x = 20 + i * 25; // 字符间距
            int y = 30; // 固定垂直位置，不再随机浮动

            // 轻微旋转效果（角度减小）
            double theta = Math.toRadians(random.nextInt(10) - 5); // -5到5度
            g.rotate(theta, x, y);

            g.drawString(String.valueOf(code.charAt(i)), x, y);

            // 恢复旋转
            g.rotate(-theta, x, y);
        }
    }

    private static Color getRandomColor() {
        Random random = new Random();
        return COLORS[random.nextInt(COLORS.length)];
    }

    /**
     * 生成随机数 最小值～最大值
     *
     * @param min 最小值
     * @param max 最大值
     */
    public static String getRandNum(int min, int max) {
        int randNum = min + (int) (Math.random() * ((max - min) + 1));
        return String.valueOf(randNum);
    }
}